﻿package ui.control
{
	import caurina.transitions.Tweener;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import org.kolonitsky.alexey.flashui.Slider;
	
	import org.kolonitsky.alexey.display.ViewManager;
	
	public class ControlPanel extends Sprite
	{
		public const MOVE_STEP:Number = 20;
		public static const PANEL_INACTIVE_ALPHA:Number = 1.0;
		public static const STICKING_DELAY:Number = 500;
		
		public var viewManager:ViewManager = null;
		
		public function get slider():Slider
		{
			if ("sldrIndex" in this)
				return this["sldrIndex"] as Slider;
			return null;
		}
		
		public function ControlPanel()
		{
			addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
		}
		
		
		//---------------------------------------------------------------------
		//
		//  Private logic
		//
		//---------------------------------------------------------------------
		
		private var timer:Timer = new Timer(100);
		private var lastZoomStep:Number = 0.0;
		private var moveX:Number = 0.0;
		private var moveY:Number = 0.0;
		
		
		
		private function onMainUpClick(event:MouseEvent):void 
		{
			timer.stop();
			if (timer.hasEventListener(TimerEvent.TIMER))
			{
				timer.removeEventListener(TimerEvent.TIMER, setMoveHandler);
				timer.removeEventListener(TimerEvent.TIMER, setZoomHandler);
			}
		}
		
		/**
		 *  Init control panel. Search all controls in skin and add
		 *  event listeners for it.
		 */
		private function addedToStageHandler(event:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE,addedToStageHandler);
			
			initButton("leftArrow", function():void { moveBy(MOVE_STEP, 0) });
			initButton("rightArrow", function():void { moveBy(-MOVE_STEP, 0) });
			initButton("topArrow", function():void { moveBy(0, MOVE_STEP) });
			initButton("bottomArrow", function():void { moveBy(0, -MOVE_STEP) });
			initButton("clearButton", onClearClick);
			
			initButton("zoomInButton", function():void { zoomBy(ViewManager.ZOOM_STEP) });
			initButton("zoomOutButton", function():void { zoomBy(-ViewManager.ZOOM_STEP) });
			
			alpha = PANEL_INACTIVE_ALPHA;
			addEventListener(MouseEvent.MOUSE_OVER, showControlPanel);
			addEventListener(MouseEvent.MOUSE_OUT, hideControlPanel);
			
			if (slider)
			{
				slider.addEventListener(Event.CHANGE, onChangeZoomByThumb);
				slider.maxPos = ViewManager.MAX_ZOOM;
				slider.minPos = ViewManager.MIN_ZOOM;
			}
			
			stage.addEventListener(MouseEvent.MOUSE_UP, onMainUpClick);
		}
		
		private function initButton(id:String, onClickHandler:Function):void
		{
			if (id in this)
			{
				trace("INFO: initButton(" + id + ")");
				var s:* = this[id];
				if (s is Sprite)
					s.buttonMode = true;
					
				s.addEventListener(MouseEvent.MOUSE_DOWN, onClickHandler);
			}
			else
			{
				trace("DEBUG: control panel don't have " + id);
			}
		}
		
		
		private function onClearClick(event:MouseEvent):void {
			viewManager.initPosition();
		}
		
		private function setMoveHandler(event:TimerEvent):void {
			viewManager.move(moveX, moveY, ViewManager.MOVE_TIME_STEP);
		}
		
		private function setZoomHandler(event:TimerEvent):void {
			viewManager.zoomBy(lastZoomStep, ViewManager.ZOOM_TIME_STEP);
		}
		
		private function zoomBy(scale:Number):void 
		{
			if (scale == 0.0)
				return;
			
			lastZoomStep = scale;
			
			viewManager.zoomBy(lastZoomStep, ViewManager.ZOOM_TIME_STEP);
			
			if (slider)
				slider.position = viewManager.currentScale;
			
			// Start sticking timer for repeat action after STICKING_DELAY
			// milisecotds if user doesn't mouse up yet
			if (timer.hasEventListener(TimerEvent.TIMER))
				timer.removeEventListener(TimerEvent.TIMER, setZoomHandler);
			timer.addEventListener(TimerEvent.TIMER, setZoomHandler);
			timer.delay = STICKING_DELAY;
			timer.start();
		}
		
		private function onChangeZoomByThumb(event:Event):void {
			
			var currentThumbPosition:Number = slider.position;
			var zoomStep:Number = currentThumbPosition - viewManager.currentScale;
//			trace("currentThumbPosition = " + currentThumbPosition, "viewManager.currentScale = " + viewManager.currentScale, "zoomStep = " + zoomStep)
			
			if (zoomStep == 0.0)
				return;
			
			lastZoomStep = zoomStep;
			
			viewManager.zoomBy(lastZoomStep, ViewManager.ZOOM_TIME_STEP);
		}
		
		private function showControlPanel(event:MouseEvent):void 
		{
			Tweener.addTween(this, {alpha: 1.0, time: 1.0});
		}
		
		private function hideControlPanel(event:MouseEvent):void 
		{
			Tweener.addTween(this, {alpha: PANEL_INACTIVE_ALPHA, time: 1.0});
		}
		
		private function moveBy(translationX:Number, translationY:Number):void 
		{
			moveX = translationX;
			moveY = translationY;
			
			viewManager.move(moveX, moveY, ViewManager.MOVE_TIME_STEP);
			
			// Start sticking timer for repeat action after STICKING_DELAY
			// milisecotds if user doesn't mouse up yet
			if (timer.hasEventListener(TimerEvent.TIMER))
				timer.removeEventListener(TimerEvent.TIMER, setMoveHandler);
			timer.addEventListener(TimerEvent.TIMER, setMoveHandler);
			timer.delay = STICKING_DELAY;
			timer.start();
		}

	}
}